package com.ljf.jwt;

import com.ljf.framework.exception.LjfTokenException;
import com.ljf.framework.result.JsonResultEnum;
import com.ljf.framework.security.token.LjfTokenManager;
import com.ljf.framework.security.token.LjfTokenService;
import com.ljf.framework.util.RsaUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Date;

/**
 * 说明：
 *
 * @Auther: lijinfeng
 * @Date: 2024/4/11
 */
public class JwtTokenServiceImpl implements LjfTokenService {

    public static final String JWT_KEY_USERID = "userId";
    public static final String JWT_KEY_PASSWORD = "password";
    public static final String JWT_KEY_AUTHORITIES = "authorities";

    @Override
    public String createToken(Long userId) {
        String token = null;
        try {
            token = generateToken(userId, "", "", RsaUtil.privateKey, (int) LjfTokenManager.getLjfTokenConfig().getTimeout());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return token;
    }

    @Override
    public Long getUserIdByToken(String token) {
        Long userId = null;
        try {
            userId = getUserInfoFromToken(token, RsaUtil.publicKey);
        } catch (Exception e) {
            e.printStackTrace();
            throw new LjfTokenException(JsonResultEnum.TOKEN_INVALID,"通过token获取用户id失败");
        }
        return userId;
    }

    @Override
    public void checkToken(String token) {
        getUserIdByToken(token);
    }

    /**
     * 私钥加密token
     * @param userId    用户名
     * @param password      密码
     * @param authorities
     * @param privateKey    私钥
     * @param expireSecond  过期时间
     * @return
     * @throws Exception
     */
    public static String generateToken(Long userId, String password, String authorities, PrivateKey privateKey, int expireSecond) throws Exception {
        return Jwts.builder()
                .claim(JWT_KEY_USERID, userId)
                .claim(JWT_KEY_PASSWORD, password)
                .claim(JWT_KEY_AUTHORITIES, authorities)
                .setExpiration(new Date(new Date().getTime() + 1000  * expireSecond))
                .signWith(SignatureAlgorithm.RS256, privateKey)
                .compact();
    }

    /**
     * 从token解析用户
     * @param token
     * @param publicKey
     * @return
     * @throws Exception
     */
    public static Long getUserInfoFromToken(String token, PublicKey publicKey) {
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(publicKey).parseClaimsJws(token);
        Claims body = claimsJws.getBody();
        return Long.parseLong(body.get(JWT_KEY_USERID).toString()) ;
    }

}
